<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>井子棋</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      .container {
        display: block;
      }
      .cell {
        display: flex;
        justify-content: center;
        align-items: center;
        float: left;
        background-color: #0f0;
        box-sizing: border-box;
        border: 1px solid #fff;
        font-size: 80px;
        color: #f00;
      }
    </style>
  </head>
  <body>
    <script>
      class TicTacToe {
        // 数据结构
        pattern = [];

        grid = 3;
        max = 3;
        widehigh = 0;

        container = null;
        // 显示状态
        status = 1;
        isWin = false;
        statusMap = {
          1: "o",
          2: "×",
          0: "",
        };
        constructor(grid = 3, max = 3, widehigh = 100) {
          this.grid = grid;
          this.max = max;
          this.widehigh = widehigh;
          this.init();
        }
        // 初始化类
        init() {
          this.initData();
          this.initDom();
          this.show();
        }
        initData() {
          for (let i = 0; i < this.grid; i++) {
            if (!this.pattern[i]) {
              this.pattern[i] = [];
            }
            for (let j = 0; j < this.grid; j++) {
              this.pattern[i][j] = 0;
            }
          }
        }
        initDom() {
          this.container = document.createElement("div");
          document.body.appendChild(this.container);
        }
        show() {
          this.container.innerHTML = "";
          for (let i = 0; i < this.grid; i++) {
            for (let j = 0; j < this.grid; j++) {
              const cell = document.createElement("div");
              cell.classList.add("cell");
              cell.innerHTML = this.statusMap[this.pattern[i][j]];

              cell.style.width = this.widehigh + "px";
              cell.style.height = this.widehigh + "px";
              cell.style.fontSize = (this.widehigh / 2) * 1.8 + "px";
              cell.addEventListener("click", () => {
                this.move(i, j);
              });
              this.container.appendChild(cell);
            }
          }
          this.container.style.width = this.grid * this.widehigh + "px";
          this.container.style.height = this.grid * this.widehigh + "px";
        }
        move(x, y) {
          if (this.pattern[x][y] || this.isWin) {
            return false;
          }
          this.pattern[x][y] = this.status;
          this.isWin = this.check(this.pattern, this.status);
          if (this.isWin) {
            console.log(this.statusMap[this.status] + "赢了");
          }
          this.show();
          this.status = 3 - this.status;
          if (this.willwin(this.status)) {
            console.log(this.statusMap[this.status] + "赢了");
          }
        }
        // 检测胜负
        check(pattern, status) {
          // 检查行
          for (let i = 0; i < this.max; i++) {
            let isWin = true;
            for (let j = 0; j < this.max; j++) {
              if (pattern[i][j] != status) {
                isWin = false;
              }
            }
            if (isWin) return isWin;
          }
          // 检查列
          for (let i = 0; i < this.max; i++) {
            let isWin = true;
            for (let j = 0; j < this.max; j++) {
              if (pattern[j][i] != status) {
                isWin = false;
              }
            }
            if (isWin) return isWin;
          }
          //   检查\
          {
            let isWin = true;
            for (let i = 0; i < this.max; i++) {
              if (pattern[i][i] != status) {
                isWin = false;
              }
            }
            if (isWin) return isWin;
          }
          // 检查 /
          {
            let isWin = true;
            for (let i = 0; i < this.max; i++) {
              if (pattern[i][this.max - 1 - i] != status) {
                isWin = false;
              }
            }
            if (isWin) return isWin;
          }
        }
        clone() {
          return JSON.parse(JSON.stringify(this.pattern));
        }
        // 检查将要赢的
        willwin(status) {
          // 检查行
          for (let i = 0; i < this.max; i++) {
            for (let j = 0; j < this.max; j++) {
              if (this.pattern[i][j] != 0) {
                continue;
              }
              let tmp = this.clone(this.pattern);
              tmp[i][j] = status;
              if (this.check(tmp, status)) {
                return true;
              }
            }
          }
        }
      }
    </script>
    <script>
      new TicTacToe();
    </script>
  </body>
</html>
